
# Copyright (c) 2014, Franklin Brauning V.  All rights reserved.
# 
#    El desarrollo inicial de esta utilidad fue producido
#    por Franklin Brauning <brauningbar@gmail.com>
# 
#    Si consideras que este codigo puede serte util, eres libre
#    de usarlo a conveniencia, pero no olvides mantener la licencia
#    y dar credito al autor.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 
#   * Redistributions of source code must retain the above copyright notice, this
#     list of conditions and the following disclaimer.
# 
#   * Redistributions in binary form must reproduce the above copyright notice,
#     this list of conditions and the following disclaimer in the documentation
#     and/or other materials provided with the distribution.
# 
#   * Neither the name of the author nor the names of its contributors may
#     be used to endorse or promote products derived from this software without
#     specific prior written permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

import datetime
import calendar

one_day = datetime.timedelta(days=1)
today = datetime.date.today
meses = ("enero","febrero","marzo","abril","mayo","junio",
         "julio","agosto","septiembre","octubre",
         "noviembre","diciembre")

meses_short = ("ene","feb","mar","abr","may","jun","jul",
               "ago","sep","oct","nov","dic")

def ultimo_dia_mes(d):
	if d.month >= 12:
		d2 = datetime.date(d.year+1, 1, 1)
	else:
		d2 = datetime.date(d.year, d.month+1, 1)
	return d2-one_day

def first_monday_of_month(year, month):
	return ((1+7-datetime.date(year, month , 1).weekday()) % 8) or 1

def first_fullweek_of_month(year, month):
	d1 = first_monday_of_month(year, month)
	return [d1+i for i in range(7)]

def whole_month_range(d):
	return (datetime.date(d.year, d.month, 1), ultimo_dia_mes(d))

def model_date(m):
	return datetime.date(m.anho, m.mes, 1)

def str_model_date(m):
	if m.anho == today().year:
		return meses[m.mes-1].title()
	return "%s del %d" % (meses[m.mes-1].title(), m.anho)

def shortstr_model_date(m):
	return "%s-%d" % (meses_short[m.mes-1], m.anho)

def nextmonth(d):
	y,m = (d.year+1, 1) if d.month >= 12 else (d.year, d.month+1)
	maxday = calendar.monthrange(year=y, month=m)[1]
	return datetime.date(y, m, min(maxday,d.day))

def prevmonth(d):
	y,m = (d.year-1, 12) if d.month <= 1 else (d.year, d.month-1)
	maxday = calendar.monthrange(year=y, month=m)[1]
	return datetime.date(y, m, min(maxday,d.day))

def nextweek(d):
	return d + datetime.timedelta(days=7)

def prevweek(d):
	return d - datetime.timedelta(days=7)


def seekmonth(d, offset):
	if offset >= 0:
		for i in range(offset):
			d = nextmonth(d)
	else:
		for i in range(-offset):
			d = prevmonth(d)
	return d

# date (target), # (meses hacia atras), # (meses hacia adelante)
def meses_offset(date, a, b):
	# vamos a extender hacia los dos lados
	meses = [date]
	for i in range(a):
		meses.insert(0, prevmonth(meses[0]))
	for i in range(b):
		meses.append(nextmonth(meses[-1]))
	return meses

def date_of_dicc(d):
	return datetime.date(int(d['year']), int(d['month']), int(d['day']))

def dicc_date(d):
	return {'year':d.year, 'month':d.month, 'day':d.day}

def strdicc_date(d):
	return {'year':str(d.year), 'month':str(d.month).zfill(2),
	        'day':str(d.day).zfill(2)}
def strdicc_daterange(d1, d2):
	dic = strdicc_date(d1)
	dic.update( {'year2':str(d2.year), 'month2':str(d2.month).zfill(2),
	             'day2':str(d2.day).zfill(2)})
	return dic

def normdicc_date(d):
    return {'year':str(d['year']),
            'month':str(d['month']).zfill(2),
            'day':str(d['day']).zfill(2)}



def hay_colision_horas(h1a, h1b, h2a, h2b):
	# la primera linea: obvio
	# 2da: caso inverso basa una sola prueba
	# 3ra: exactamente el mismo rango
	return (h1a < h2a < h1b) or (h1a < h2b < h1b) or \
	       (h2a < h1a < h2b) or \
	       (h1a == h2a and h1b == h2b)


def minutes(t):
	return t.hour * 60 + t.minute

